package com.example.demo.service.impl;

import com.example.demo.entity.SysPermission;
import com.example.demo.entity.SysRole;
import com.example.demo.entity.SysUser;
import com.example.demo.repository.SysPermissionRepository;
import com.example.demo.repository.SysUserRepository;
import com.example.demo.service.RbacService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.Set;

/**
 * Copyright(C), 2020-2021, AmbroseCdMeng
 * FileName:    RbacServiceImpl
 * Author:      AmbroseCdMeng
 * Date:        2021/3/5 15:12
 * Description: 实现基于RBAC权限控制功能
 * History:
 * <author>     <time>      <version>       <desc>
 * 作者姓名     修改时间        版本号           描述
 */
@Component("rbacService")
public class RbacServiceImpl implements RbacService {
    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Autowired
    private SysPermissionRepository sysPermissionRepository;
    @Autowired
    private SysUserRepository sysUserRepository;

    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        Object principal = authentication.getPrincipal();
        boolean hasPermission = false;
        if (principal instanceof UserDetails) {
            // 登录的用户名
            String userName = ((UserDetails) principal).getUsername();
            // 获取请求登录的 URL
            Set<String> urls = new HashSet<>(); // 用户具备的系统资源集合，从数据库读取
            SysUser sysUser = sysUserRepository.findByName(userName);
            for (SysRole role : sysUser.getRoles()) {
                for (SysPermission permission : role.getPermissions()) {
                    urls.add(permission.getUrl());
                }
            }
            for (String url : urls) {
                if (antPathMatcher.match(url, request.getRequestURI())) {
                    hasPermission = true;
                    break;
                }
            }
        }
        return hasPermission;
    }
}
